package com.eudon.design_pattern.behavioral.visitor;

/**
 * @author eudon
 * @description 文件压缩访问者 - 访问者模式中的具体访问者
 * @date 2025/9/3
 * @email syd19970616@gmail.com
 * @address <a href="https://gitee.com/eudon">Gitee</a>
 */
public class Compressor implements Visitor {
    
    /**
     * 访问PDF文件，执行压缩操作
     * 根据PDF文件的特性（页数、是否包含图片）来选择最优的压缩策略
     * 
     * @param pdfFile PDF文件对象
     */
    @Override
    public void visit(PdfFile pdfFile) {
        System.out.println("=== 文件压缩器正在处理PDF文件 ===");
        System.out.println("文件信息: " + pdfFile.toString());
        
        // 计算原始文件大小
        double originalSize = pdfFile.getFileSize();
        System.out.println("原始文件大小: " + formatFileSize(originalSize));
        
        // 根据PDF文件特性选择压缩策略
        double compressionRatio;
        if (pdfFile.hasImages()) {
            System.out.println("检测到图片内容，启用图片压缩算法...");
            System.out.println("正在压缩图片质量和分辨率...");
            compressionRatio = 0.4; // 包含图片的PDF压缩率更高
        } else {
            System.out.println("纯文本PDF，启用文本优化压缩...");
            System.out.println("正在优化字体和文本编码...");
            compressionRatio = 0.7; // 纯文本PDF压缩率较低
        }
        
        // 根据页数调整压缩策略
        if (pdfFile.getPageCount() > 50) {
            System.out.println("大文档检测，启用分页压缩优化...");
            compressionRatio -= 0.1; // 大文档可以获得更好的压缩率
        }
        
        // 计算压缩后大小
        double compressedSize = originalSize * compressionRatio;
        double savedSpace = originalSize - compressedSize;
        double savedPercentage = (savedSpace / originalSize) * 100;
        
        System.out.println("压缩完成！");
        System.out.println("压缩后大小: " + formatFileSize(compressedSize));
        System.out.println("节省空间: " + formatFileSize(savedSpace) + " (" + String.format("%.1f", savedPercentage) + "%)");
        System.out.println("压缩文件已保存到: " + getCompressedFileName(pdfFile.getFileName()));
        System.out.println();
    }
    
    /**
     * 访问PPT文件，执行压缩操作
     * 根据PPT文件的特性（幻灯片数量、动画效果）来选择最优的压缩策略
     * 
     * @param pptFile PPT文件对象
     */
    @Override
    public void visit(PPTFile pptFile) {
        System.out.println("=== 文件压缩器正在处理PPT文件 ===");
        System.out.println("文件信息: " + pptFile.toString());
        
        // 计算原始文件大小
        double originalSize = pptFile.getFileSize();
        System.out.println("原始文件大小: " + formatFileSize(originalSize));
        
        // 根据PPT文件特性选择压缩策略
        double compressionRatio = 0.6; // PPT基础压缩率
        
        if (pptFile.hasAnimations()) {
            System.out.println("检测到动画效果，启用动画优化压缩...");
            System.out.println("正在优化动画序列和过渡效果...");
            compressionRatio = 0.5; // 动画文件压缩率更高
        } else {
            System.out.println("静态演示文稿，启用标准压缩...");
            System.out.println("正在压缩图片和优化布局...");
        }
        
        // 根据幻灯片数量调整压缩策略
        if (pptFile.getSlideCount() > 30) {
            System.out.println("大型演示文稿检测，启用批量优化...");
            compressionRatio -= 0.1;
        }
        
        // 根据演示时长优化
        if (pptFile.getDurationMinutes() > 60) {
            System.out.println("长时演示检测，启用深度压缩...");
            compressionRatio -= 0.05;
        }
        
        // 计算压缩后大小
        double compressedSize = originalSize * compressionRatio;
        double savedSpace = originalSize - compressedSize;
        double savedPercentage = (savedSpace / originalSize) * 100;
        
        System.out.println("压缩完成！");
        System.out.println("压缩后大小: " + formatFileSize(compressedSize));
        System.out.println("节省空间: " + formatFileSize(savedSpace) + " (" + String.format("%.1f", savedPercentage) + "%)");
        System.out.println("压缩文件已保存到: " + getCompressedFileName(pptFile.getFileName()));
        System.out.println();
    }
    
    /**
     * 访问Word文件，执行压缩操作
     * 根据Word文件的特性（字数、表格、图片）来选择最优的压缩策略
     * 
     * @param wordFile Word文件对象
     */
    @Override
    public void visit(WordFile wordFile) {
        System.out.println("=== 文件压缩器正在处理Word文件 ===");
        System.out.println("文件信息: " + wordFile.toString());
        
        // 计算原始文件大小
        double originalSize = wordFile.getFileSize();
        System.out.println("原始文件大小: " + formatFileSize(originalSize));
        
        // 根据Word文件特性选择压缩策略
        double compressionRatio = 0.8; // Word基础压缩率
        
        System.out.println("正在分析文档内容结构...");
        
        if (wordFile.hasImages()) {
            System.out.println("检测到图片内容，启用图片压缩...");
            compressionRatio = 0.5; // 包含图片的文档压缩率更高
        }
        
        if (wordFile.hasTables()) {
            System.out.println("检测到表格内容，启用表格优化...");
            compressionRatio -= 0.1; // 表格可以进一步压缩
        }
        
        // 根据文档大小调整压缩策略
        if (wordFile.getWordCount() > 10000) {
            System.out.println("大型文档检测，启用文本压缩算法...");
            compressionRatio -= 0.1;
        }
        
        // 版本兼容性优化
        System.out.println("文档版本: " + wordFile.getVersion() + " - 启用版本优化压缩");
        if ("2019".equals(wordFile.getVersion()) || "2021".equals(wordFile.getVersion())) {
            compressionRatio -= 0.05; // 新版本格式压缩效果更好
        }
        
        // 计算压缩后大小
        double compressedSize = originalSize * compressionRatio;
        double savedSpace = originalSize - compressedSize;
        double savedPercentage = (savedSpace / originalSize) * 100;
        
        System.out.println("压缩完成！");
        System.out.println("压缩后大小: " + formatFileSize(compressedSize));
        System.out.println("节省空间: " + formatFileSize(savedSpace) + " (" + String.format("%.1f", savedPercentage) + "%)");
        System.out.println("压缩文件已保存到: " + getCompressedFileName(wordFile.getFileName()));
        System.out.println();
    }
    
    @Override
    public String getVisitorName() {
        return "文件压缩器";
    }
    
    /**
     * 格式化文件大小显示
     * @param sizeInMB 文件大小（MB）
     * @return 格式化后的文件大小字符串
     */
    private String formatFileSize(double sizeInMB) {
        if (sizeInMB >= 1024) {
            return String.format("%.2f GB", sizeInMB / 1024);
        } else {
            return String.format("%.2f MB", sizeInMB);
        }
    }
    
    /**
     * 生成压缩后的文件名
     * @param originalFileName 原始文件名
     * @return 压缩后的文件名
     */
    private String getCompressedFileName(String originalFileName) {
        int lastDotIndex = originalFileName.lastIndexOf('.');
        if (lastDotIndex > 0) {
            String baseName = originalFileName.substring(0, lastDotIndex);
            String extension = originalFileName.substring(lastDotIndex);
            return baseName + "_compressed" + extension;
        } else {
            return originalFileName + "_compressed";
        }
    }
}